<template>
  <div class="app-container">
    <div class="content">
      <div class="x-left">

        <div class="x-tabs">
          <div class="x-tab-item" :class="{'active':active == item.value}" v-for="(item,index) in tabs" :key="index" @click="handleChangeTab(item.value)">{{item.label}}</div>
        </div>
        <div class="x-search">
          <div class="search-box">
            <el-input placeholder="请输入内容" v-model="queryParams.name" clearable @change="initList"></el-input>
          </div>
        </div>

        <div class="x-list">
          <div class="x-li-item" v-for="(item,index) in list" :key="index">
            <div class="p-item" :class="{'open': item.open}" @click="handleChange(item,index)"><i class="expanded el-tree-node__expand-icon el-icon-caret-right"></i><span>{{item.name||'未命名'}}</span></div>
            <div class="child-list" :class="{'show': item.open}">
              <div class="x-child-item" :data-current="JSON.stringify(currentItem)" :data-ct="(currentItem.memberId === c.memberId)" :data-c="JSON.stringify(c)" :class="{'current':(c.memberId && c.memberId == currentItem.memberId)|| (c.code && c.code == currentItem.code)}" v-for="(c, idx) in item.members" :key="idx" @click="handleClickItem(c,index)">
                <span v-if="c.online==1" class="online-status"></span>
                <span>{{showName(c)}}</span>
              </div>
            </div>
          </div>
          <!-- <el-tree
          ref="tree"
          node-key="code"
          :data="list"
          :props="{ label: '_name', children: 'list' }"
          :default-expand-all="true"
          :highlight-current="true"
          :check-on-click-node="true"
          :expand-on-click-node="false"
          @node-click="deptChange"
        ></el-tree> -->
        </div>
      </div>

      <div class="right">
        <mapTrack ref="mapTrack"></mapTrack>
        <UserCard ref="userCard" v-if="showUserCard" :currentDay="currentDate" :timeList="timesList" :userInfo="currentItem" :loading="isLoading" @change="onChangeDate" @handleClickBtn="onHandleClickBtn" @changeTime="onChangeWorkTime" @handleClickClock="handleClickClock"></UserCard>
        <timerBarVue ref="timerBar" v-if="showTimeBar" @handlePlay="onHandlePlay" @handleOut="onHandleOut" @dragStart="onDragStart" @dragEnd="onDragEnd"></timerBarVue>

        <components :is="componentName" @close="componentName=null" :detail="eventDetail" :options="moniterChannels"></components>
      </div>
    </div>
  </div>
</template>

<script>
import UserCard from "./components/userCard.vue";
import mapTrack from "./components/mapTrack.vue";
import timerBarVue from "./components/timerBar.vue";
import EventInfo from "./components/eventInfo.vue";
import Moniter from './components/monitor.vue'

import {
  getCarList,
  getDeviceInfoList,
  getHistoryRecord,
  getWorkTimeByMemberId,
  getCheckArea,
  getPatrolList,
  getPatrolHistory,
  getClientChannels,
  listByPatrolRecord
} from "@/api/unify";
import {getPersonList} from '@/api/person'
import PreviewPath from "./js/PreviewPath";
import AnimateMarker from "./js/AnimateMarker";
import CheckArea from "./js/CheckArea";
import { formatTimeHM } from "@/utils/index";
import GPS from '@/utils/gps'

function formatData(data) {
  if (data && data.length) {
    const mapList = data.reduce((prev, curr) => {
      prev[`${curr.groupId}-${curr.groupName}`]
        ? prev[`${curr.groupId}-${curr.groupName}`].push(curr)
        : ((prev[`${curr.groupId}-${curr.groupName}`] = []),
          prev[`${curr.groupId}-${curr.groupName}`].push(curr));
      return prev;
    }, {});
    let list = [];
    for (let k in mapList) {
      const obj = {};
      const names = k.split("-");
      obj.name = names[1];
      obj.id = names[0];
      obj.members = mapList[k];
      obj.open = false;
      list.push(obj);
    }
    return list;
  } else {
    return [];
  }
}

let previewPath = null;
let animateMarker = null;
let checkArea = null; // 工作范围


export default {
  name: "Card",
  components: {
    UserCard,
    mapTrack,
    timerBarVue,
    EventInfo,
  },
  data() {
    let $day = this.parseTime(new Date(), "{y}-{m}-{d}");
    return {
        tabs: [{label: '人员', value: 1}, {label: '车辆设备', value: 2}, {label: '巡逻车', value: 3}],
        loading:false,
        lastClickTime: 0,
        current: "",
        list: [],
        active: 1,
        queryParams: {
            name: "",
            pageSize: 999
        },
        currentDate: $day,
        currentItem: {},
        showUserCard: false,
        isLoading: false,
        allPathData: [], // 当前所有轨迹
        currentPathData: [], // 当前轨迹
        segmentPathData: [], // 分段后的轨迹
        showTimeBar: false,
        timesList: [], // 时间段
        componentName: null,
        eventDetail: {},
        moniterChannels: []
    };
  },
  created() {
    this.getList();
  },
  deactivated() {
    
  },
  beforeDestroy() {
    console.log("beforeDestroy")
    this.currentItem = {};
    this.currentPathData = [];
    this.showUserCard = false;
    console.log("清除数据----------------------")
    this.clearLastMap();
    previewPath = null;
  },
  methods: {
    showName(c) {
      return this.active == 2 ? c.code + "（" + c.driverMemberName + "）" : c.memberName || c.driverMemberName || c.name;
    },
    // 获取列表
    async getList() {
      try {        
        const res = await getPersonList({pageSize: 999, _memberName_: this.queryParams.name});
        this.list = formatData(res.data);
        this.loading = false;
      } catch (error) {
        this.loading = false;
        console.log("getPersonList error", error)
      }
    },
    async getCarList() {
      try {
        const res = await getCarList({ pageSize: 999, _driverMemberName_: this.queryParams.name });
        this.list = formatData(res.data);
        this.loading = false;
      } catch (error) {
        this.loading = false;
        console.log("getCarList error", error)
      }
    },
    async getDeviceInfoList() {
      try {
        const res = await getDeviceInfoList({ type: "BIKE", pageSize: 999, _name_: this.queryParams.name });
        this.list = formatData(res.data);
        this.loading = false;
      } catch (error) {
        this.loading = false;
        console.log("getDeviceInfoList error", error)
      }
    },
    initList() {
        this.currentItem = {};
        this.destroyPreview();
        this.destroyAnimate();
        this.list = [];
        this.loading = true;
        if (this.active == 1) {
            this.getList();
        } else if (this.active == 2) {
            this.getCarList();
        } else {
            this.getDeviceInfoList();
        }
        
    },
    // 切换tab
    handleChangeTab(index) {
        if(this.loading) return this.$message.warning("数据加载中...")
      this.showUserCard = false;
      this.active = index;
      this.clearLastMap()
      this.initList();
      this.currentItem = {}
    },
    handleChange(item) {
      this.$set(item, "open", !item.open);
      this.$forceUpdate();
    //   this.currentItem = {};
    },
    // 选择人员
    async handleClickItem(item, index) {
      const currentTime = +new Date();
      if (currentTime - this.lastClickTime < 2500) {
        return;
      }
    //   console.log(item);
      this.lastClickTime = currentTime;
      this.timesList.length = 0;
      this.segmentPathData.length = 0;
      this.showTimeBar = false;
      this.currentItem = structuredClone(item);

      this.currentDate = this.parseTime(new Date(), "{y}-{m}-{d}");
      if (this.active == 1 && !item.cardNum) {
        return this.$message.error("暂未绑定工牌！");
      }
        this.setShowPlayBtn(false)
        this.setShowMonitorBtn(false)
        this.setShowClock(false)
        if(this.active == 2) {
            this.getClientChannels()
        }
      this.getCheckArea();
      this.getData();
    },
    // 查询监控频道
    async getClientChannels() {
      try {
        if(!this.currentItem.thirdCode) return;
        const res = await getClientChannels({thirdCode: this.currentItem.thirdCode})
        if(res.data && res.data.length) {
          this.moniterChannels = res.data;
          this.setShowMonitorBtn(true)
        }else{
          this.setShowMonitorBtn(false)
        }
      } catch (error) {

      }
    },
    // 查询工作范围
    async getCheckArea() {
      try {
        this.destroyCheckarea();
        if (!this.currentItem.memberId) return;
        const res = await getCheckArea({ memberId: this.currentItem.memberId });
        if (res.code == 1 && res.data) {
          checkArea = new CheckArea(this.$refs.mapTrack.map, res.data);
        }
      } catch (error) {}
    },
    async getData(clearCheck) {
      try {
        this.showUserCard = true;
        this.setDisabledDate(false)
        if(this.active == 1) {
            this.setShowClock(true)
        }
        this.clearLastMap(clearCheck)

        this.allPathData = [];
        this.timesList = [];
        this.segmentPathData.length = 0;
        this.showUserCard = true;
        this.setShowPlayBtn(false)
        let code = this.currentItem.cardNum || null;

        if (this.active == 2) {
          code = this.currentItem.thirdCode;
        }
        if (this.active == 3) {
            // 巡查车逻辑
          code = this.currentItem.code;
          const result = await listByPatrolRecord({
            _startTime_: this.currentDate,
            deviceCode: code,
            pageSize: 999,
          });
          if (result.data && result.data.length) {
            result.data.forEach((item) => {
              const stime = this.parseTime(item.startTime, "{h}:{i}");
              const etime = this.parseTime(item.endTime, "{h}:{i}");
              this.timesList.push({
                formatStartTime: stime,
                formatEndTime: etime||'巡查中',
                ...item,
              });
            });
            this.onChangeWorkTime(0, this.timesList[0])
          }else{
            return this.$message.error("暂无数据~~~");
          }
          return;
        }

        if(!code) {
            return this.$message.error("暂未绑定编码~~~");
        }
        const { data } = await getHistoryRecord({
          code: code,
          type: this.active == 1 ? 'CARD': 'CAR',
          day: this.currentDate,
        });

        if (!data || data.length == 0) {            
            this.$message.error("暂无轨迹~~~");
        }
        this.allPathData = data||[];

        // 如果是车辆设备，不查排班
        if (this.active == 2 || this.active == 3) {
          this.currentPathData = data;
          this.drawPreviewPath();
          return;
        }
        const res = await getWorkTimeByMemberId({
          memberId: this.currentItem.memberId,
          day: this.currentDate,
        });
        if (res.data && res.data.length > 0) {
          const firstGroupClazz = res.data[0];
          const timeSegment = JSON.parse(firstGroupClazz.timeSegment);
          timeSegment.map((item, index) => {
            const obj = {};
            obj.start = `${this.currentDate} ${item.startTime}`;
            obj.startTime = item.startTime;
            obj.formatStartTime = formatTimeHM(item.startTime);
            obj.startTimeTemp = +new Date(obj.start);
            obj.end = `${this.currentDate} ${item.endTime}`;
            obj.endTime = item.endTime;
            obj.formatEndTime = formatTimeHM(item.endTime);
            obj.endTimeTemp = +new Date(obj.end);
            this.segmentPathData[index] = [];
            this.allPathData.map((d) => {
              const timeStemp = +new Date(d.gmtReport);
              if (
                timeStemp >= obj.startTimeTemp &&
                timeStemp <= obj.endTimeTemp
              ) {
                this.segmentPathData[index].push(d);
              }
            });

            this.timesList.push(obj);
          });

          // console.log(this.timesList)
          // console.log(this.segmentPathData)

          this.currentPathData = structuredClone(this.segmentPathData[0]);
          // 默认展示第一个时间段的预览轨迹
          this.drawPreviewPath();
          
        } else {
          this.timesList = [];
          return this.$message.error("暂无排班~~~");
        }
      } catch (error) {
        console.log("----------------------", error);
      }
    },
    // 显示预览轨迹
    drawPreviewPath(type='normal', eventData=[]) {
      if (this.currentPathData.length == 0) {
        this.setShowPlayBtn(false)
        let msg = this.active == 1? "当前排班时段没有轨迹，请试试其他时段~~" : "当前无轨迹~~";
        return this.$message.error(msg);
      }

        this.setShowPlayBtn(true)
        previewPath = new PreviewPath(this.$refs.mapTrack.map, this.currentPathData, type, eventData);

        previewPath.on("clickMarker", e => {
            // console.log('eeeee',e)
            this.componentName = EventInfo;
            this.eventDetail = e;
        })
    },
    setShowMonitorBtn(flag) {
      this.$nextTick(_=>{
        this.$refs['userCard'] && this.$refs['userCard'].setShowMonitor(flag)
      })
    },
    setShowPlayBtn(flag) {
      this.$nextTick(_=>{
        this.$refs['userCard'] && this.$refs['userCard'].setShowPlaybtn(flag)
      })
    },
    setDisabledDate(flag) {
      this.$nextTick(_=>{
        this.$refs['userCard'] && this.$refs['userCard'].setDisabled(flag)
      })
    },
    setShowClock(flag) {
        this.$nextTick(_=>{
            this.$refs['userCard'] && this.$refs['userCard'].setShowClock(flag)
        })
    },
    // 清除上一次的覆盖物
    clearLastMap(clearCheck=true) {
      this.destroyPreview();
      this.destroyAnimate();
    //   console.log("是否清除工作范围：", clearCheck)
    clearCheck && this.destroyCheckarea()
      this.currentPathData.length = 0;
      this.$refs.mapTrack.clearMapMarker()
    },
    // 销毁预览轨迹
    destroyPreview() {
      if (previewPath) {
        previewPath.destroy();
      }
        previewPath = null;
    },
    // 销毁动画轨迹
    destroyAnimate() {
      if (animateMarker) {
        animateMarker.destroy();
      }
        animateMarker = null;
    },
    // 销毁工作范围
    destroyCheckarea() {
      if (checkArea) {
        checkArea.destroy();
      }
        checkArea = null;
    },
    // 切换日期
    onChangeDate(day) {
      this.currentDate = day;
      this.getData(false);
    },
    // 切换班组时间
    async onChangeWorkTime(index, item) {
      try {
        this.clearLastMap(false);
        this.showTimeBar = false;
        if (this.active == 3) {
          // 巡逻车逻辑
            const res = await getPatrolHistory({id: item.id});
            this.currentPathData = res.data.location.map(item => {
                item.gmtReport = item.gmtCreate;
                if(item.location) {
                    const location = item.location.split(',');
                    item.longitude = location[0];
                    item.latitude = location[1];
                    return item;
                }
                item.longitude = null;
                item.latitude = null;
                return item;
            });
            this.drawPreviewPath('xlc', res.data.warn)
            return;
        }

        if ( this.segmentPathData[index] && this.segmentPathData[index].length > 1 ) {
          this.currentPathData = structuredClone(this.segmentPathData[index]);
        } else {
          this.currentPathData = [];
        }
        this.drawPreviewPath();
      } catch (error) {
        console.log("error", error)
      }
    },
    // 点击轨迹回放
    onHandleClickBtn(type) {
        if(type == 'monitor') {
        this.startMonitorFn()
      }else{      
        this.setDisabledDate(true);
        this.destroyPreview();
        this.destroyAnimate();
        if (!this.currentPathData.length) return;
        animateMarker = new AnimateMarker(
            this.$refs.mapTrack.map,
            this.currentPathData
        );
        animateMarker.on("playEnd", () => {
            this.$refs.timerBar.setPlayStatus(false);
        });
        animateMarker.on("updateTime", (data) => {
            this.$refs.timerBar.setIframe(data, this.currentDate);
        });
        this.showTimeBar = true;
        this.$nextTick((_) => {
            this.$refs.timerBar.setLine(this.currentPathData, this.currentDate);
        });
      }
      // animateMarker.play()
    },
    startMonitorFn() {
      console.log(this.currentItem)
      this.componentName = Moniter;
    },

    // 点击上下班打卡，显示点位
    handleClickClock({type, check}) {
        const typeKey = type == 1 ? 'clockIn': 'clockOut'
        if(check) {
            const list = this.allPathData.filter(item => {
                return item.type ==type;
            })
            console.log(list)
            if(!list || list.length==0) {
                this.$message.error("暂未打卡！")
            }
            this.$refs.mapTrack.createMarker(list, typeKey)
        }else{
            this.$refs.mapTrack.clearMapMarker(typeKey)
        }
    },

    /* 时间轴控制 */
    // 播放/ 停止
    onHandlePlay(isPlay) {
      if (animateMarker) {
        isPlay ? animateMarker.play() : animateMarker.stop();
      }
    },
    // 退出
    onHandleOut() {
      this.$refs["userCard"].setDisabled(false);
      this.destroyAnimate();
      this.showTimeBar = false;
    },
    onDragStart() {
      this.onHandlePlay(false);
    },
    onDragEnd(timestamp) {
      animateMarker.setPlayPos(timestamp);
    },
  },
};
</script>
<style lang="scss">
@import "./style/index.scss";
</style>
<style lang="scss" scoped>
.app-container {
  background: rgba(247, 246, 251, 1);
  .content {
    display: flex;
    .x-left {
      width: 300px;
      height: calc(100vh - 220px);
      flex-shrink: 0;
      margin-right: 20px;
    }
    .right {
      position: relative;
      flex: 1;
      height: calc(100vh - 150px);
      .map {
        width: 100%;
        height: 100%;
      }
    }
  }
}

.x-tabs {
  display: flex;
  justify-content: space-between;
  .x-tab-item {
    width: 28%;
    border: 1px solid #ccc;
    border-radius: 5px;
    text-align: center;
    height: 38px;
    line-height: 38px;
    cursor: pointer;
  }
  .active {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
  }
}

.x-search {
  margin-top: 20px;
  display: flex;
  .search-box {
    flex: 1;
  }
  ::v-deep {
    .el-select {
      width: 100px;
    }
  }
}

.x-list {
  margin-top: 20px;
  height: 95%;
  overflow-y: auto;
  padding-bottom: 80px;
  border-radius: 10px;
  background: #fff;
  .x-li-item {
    border-bottom: 2px solid #e4e4e457;
    .p-item {
      padding: 8px 0;
      cursor: default;
      font-size: 14px;
      padding-left: 10px;
      position: relative;
      &:hover {
        background: #40a0ff42;
      }
      .el-tree-node__expand-icon {
        color: #000;
        font-size: 14px;
        padding: 5px;
        transform: rotate(0deg);
        transition: transform 0.3s ease-in-out;
      }
      &.open {
        .el-tree-node__expand-icon {
          transform: rotate(90deg);
        }
      }
    }
  }

  .child-list {
    transition: display 1s;
    display: none;
    &.show {
      transition: 1s;
      display: block;
    }
    .x-child-item {
      border-radius: 5px;
      padding: 5px 0;
      padding-left: 48px;
      font-size: 14px;
      position: relative;
      .online-status {
        position: absolute;
        display: inline-block;
        width: 8px;
        height: 8px;
        background: #09da02;
        border-radius: 50%;
        top: 50%;
        left: 35px;
        transform: translateY(-50%);
      }
      &:hover {
        background: #40a0ff93;
        color: #ffffff;
      }
      &.current {
        color: #ffffff;
        background: #40a0ffe1;
        font-weight: 700;
      }
    }
  }
}
</style>
<style scoped>
/* 宽度和高度 */
::-webkit-scrollbar {
  width: 8px; /* 竖向滚动条宽度 */
  height: 8px; /* 横向滚动条高度 */
}

/* 轨道背景 */
::-webkit-scrollbar-track {
  background: #f1f1f1;
}

/* 滑块 */
::-webkit-scrollbar-thumb {
  background: #bebebe;
  border-radius: 10px;
}

/* 当滚动条被悬停时的滑块 */
::-webkit-scrollbar-thumb:hover {
  background: #afafaf;
}

::-webkit-scrollbar-corner {
}
</style>
